home *** CD-ROM | disk | FTP | other *** search
- _PORTING UNIX TO THE 386_
- by William Frederick Jolitz and Lynne Greer Jolitz
-
- [LISTING ONE]
-
- /* [Excerpted from /sys/i386/isa/icu.h] */
- ...
- /* Macro's for interrupt level priority masks (used in assembly code) */
- /* mask additional interrupts */
- #define ORPL(m) \
- cli ; /* disable interrupts */ \
- movw m , %dx ; /* get the mask */ \
- inb $ IO_ICU1+1, %al ; /* next, get low order mask */ \
- xchgb %dl, %al ; /* switch the old with the new */ \
- orb %dl, %al ; /* finally, or it in! */ \
- outb %al, $ IO_ICU1+1 ; \
- inb $0x84, %al ; \
- inb $ IO_ICU2+1, %al ; /* next, get high order mask */ \
- xchgb %dh, %al ; /* switch the old with the new */ \
- orb %dh, %al ; /* finally, or it in! */ \
- outb %al, $ IO_ICU2+1 ; \
- inb $0x84, %al ; /* flush write buffer, delay bus cycle */ \
- movzwl %dx, %eax ; /* return old priority */ \
- sti ; /* enable interrupts */
- /* force interrupt mask */
- #define SETPL(v) \
- cli ; /* disable interrupts */ \
- movw v , %dx ; \
- inb $ IO_ICU1+1, %al ; /* next, get low order mask */ \
- xchgb %dl, %al ; /* switch the old with the new */ \
- outb %al, $ IO_ICU1+1 ; \
- inb $0x84, %al ; \
- inb $ IO_ICU2+1, %al ; /* next, get high order mask */ \
- xchgb %dh, %al ; /* switch the copy with the new */ \
- outb %al, $ IO_ICU2+1 ; \
- inb $0x84, %al ; /* flush write buffer, delay bus cycle */ \
- movzwl %dx, %eax ; /* return old priority */ \
- sti ; /* enable interrupts */
- /* Mask a group of interrupts atomically - interrupt entry */
- #define INTR(unit,mask,offst) \
- pushl $0 ; /* first, build a trap frame for ... */ \
- pushl $ T_ASTFLT ; /* ... possible rescheduling that may occur */ \
- pushal ; \
- nop ; \
- movb $0x20, %al ; /* next, as soon as possible send EOI ... */ \
- outb %al, $ IO_ICU1 ; /* ...so in service bit may be cleared ...*/ \
- inb $0x84, %al ; /* ... ASAP */ \
- movb $0x20, %al ; /* likewise, the other one as well */ \
- outb %al,$ IO_ICU2 ; \
- inb $0x84,%al ; \
- pushl %ds ; /* save our data and extra segments ... */ \
- pushl %es ; \
- movw $0x10, %ax ; /* ... and reload with kernel's own */ \
- movw %ax, %ds ; \
- movw %ax, %es ; \
- incl _cnt+V_INTR ; /* tally interrupts */ \
- incl _isa_intr + offst * 4 ; \
- movw mask , %dx ; /* assert group mask */ \
-
- inb $ IO_ICU1+1, %al ; /* next, get low order mask */ \
- xchgb %dl, %al ; /* switch the old with the new */ \
- orb %dl, %al ; /* finally, or it in! */ \
- outb %al, $ IO_ICU1+1 ; \
- inb $0x84,%al ; \
- inb $ IO_ICU2+1, %al ; /* next, get high order mask */ \
- xchgb %dh, %al ; /* switch the old with the new */ \
- orb %dh, %al ; /* finally, or it in! */ \
- outb %al, $ IO_ICU2+1 ; \
- inb $0x84, %al ; \
- pushl %edx ; /* save old mask for when we return */ \
- pushl $ unit ; /* finish off interrupt frame with unit # */ \
- sti ; /* and allow other unmasked interrupts */
- ...
-
-
-
- [LISTING TWO]
-
- /* AT/386 -- Interrupt vector routines -- Generated by config program */
-
- #include "machine/isa/isa.h"
- #include "machine/isa/icu.h"
-
- #define VEC(name) .align 4; .globl _V/**/name; _V/**/name:
- .globl _hardclock
- VEC(clk)
- INTR(0, ___highmask__, 0)
- call _hardclock
- INTREXIT1
-
- .globl _wdintr, _wd0mask
- .data
- _wd0mask: .long 0
- .text
- VEC(wd0)
- INTR(0, ___biomask__, 1)
- call _wdintr
- INTREXIT2
-
- .globl _fdintr, _fd0mask
- .data
- _fd0mask: .long 0
- .text
- VEC(fd0)
- INTR(0, ___biomask__, 2)
- call _fdintr
- INTREXIT1
-
- .globl _cnrint, _cn0mask
- .data
- _cn0mask: .long 0
- .text
- VEC(cn0)
- INTR(0, ___ttymask__, 3)
- call _cnrint
- INTREXIT1
-
- .globl _npxintr, _npx0mask
- .data
- _npx0mask: .long 0
- .text
- VEC(npx0)
- INTR(0, _npx0mask, 4)
- call _npxintr
- INTREXIT2
-
- .globl _comintr, _com0mask
- .data
- _com0mask: .long 0
- .text
- VEC(com0)
- INTR(0, ___ttymask__, 5)
- call _comintr
- INTREXIT1
-
- .globl _weintr, _we0mask
- .data
- _we0mask: .long 0
- .text
- VEC(we0)
- INTR(0, ___netmask__, 6)
- call _weintr
- INTREXIT1
-
- .globl _lptintr, _lpt0mask
- .data
- _lpt0mask: .long 0
- .text
- VEC(lpt0)
- INTR(0, ___ttymask__, 7)
- call _lptintr
- INTREXIT1
-
-
-
-
- [LISTING THREE]
-
- /* [Excerpted from /sys/i386/isa/icu.h] */
- ...
- /* First eight interrupts (ICU1) */
- #define INTREXIT1 \
- jmp doreti
- /* Second eight interrupts (ICU2) */
- #define INTREXIT2 \
- jmp doreti
- ...
- /* [Excerpted from /sys/i386/isa/icu.s] */
- ...
- /* Handle return from interrupt after device handler finishes */
- doreti:
- /* move to a trap frame */
- cli /* interrupts off while we work ... */
- popl %ebx /* remove unit number */
- popl %eax /* get previous priority mask */
-
- /* restore previous mask */
- movw %ax, %cx
- outb %al, $ IO_ICU1+1
- inb $0x84, %al
- movb %ah, %al
- outb %al, $ IO_ICU2+1
- inb $0x84, %al
-
- /* are we at interrupt level / nested interrupt already ? */
- cmpw ___nonemask__, %cx
- jne 3f
-
- /* do we need to process an network software interrupt ? */
- cmpl $0, _netisr
- je 2f
- btsl $ NETISR_PROCESS, _netisr
- jb 2f
-
- #include "../net/netisr.h"
- #define DOCALL(n, s, c) ; \
- .globl c ; \
- btrl $ s , n ; \
- jnb 1f ; \
- call c ; \
- 1:
- /* process a network software interrupt */
- sti
- DOCALL(_netisr, NETISR_RAW, _rawintr)
- #ifdef INET
- DOCALL(_netisr, NETISR_IP, _ipintr)
- #endif
- #ifdef IMP
- DOCALL(_netisr, NETISR_IMP, _impintr)
- #endif
- #ifdef NS
- DOCALL(_netisr, NETISR_NS, _nsintr)
- #endif
- btrl $ NETISR_PROCESS, _netisr
- 2:
- /* do we need to process a software clock "interrupt" */
- cli
- btrl $ SCLK_NEED, ___softclock__
- jnb 1f
- btsl $ SCLK_PROCESS, ___softclock__
- jb 1f
-
- /* process a software clock "interrupt" */
- sti
- pushl ___nonemask__ /* to an interrupt frame again */
- pushl %ebx
- call _softclock
- popl %eax /* back to trap frame for possible AST */
- popl %eax
- btrl $ SCLK_PROCESS, ___softclock__
- 1:
- /* see if we need to process an AST (rescheduling) fault */
- cmpw $0x1f, tCS*4(%esp) /* were we executing from a user mode ... */
- jne 3f /* ... code selector? */
- DOCALL(___ast__, AST_NEED, _trap);
- 3:
- /* restore the state and return */
- popl %es
- popl %ds
- popal
- nop
- addl $8, %esp
- iret
- ...
-
-